package com.bfly.core.interceptor;

import com.bfly.common.reflect.ReflectUtils;
import com.bfly.core.cache.EhCacheUtil;
import com.bfly.core.cache.SysConfigCacheUtil;
import com.bfly.core.context.*;
import com.bfly.core.enums.SysError;
import com.bfly.core.exception.ServiceResponseException;
import com.bfly.core.exception.UnLoginException;
import com.bfly.mall.system.dto.WXMiniProConfigDTO;
import com.bfly.mall.user.entity.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 前端(小程序,H5,APP)请求拦截器
 * 需要校验头部token,需要用户登录授权的接口需要校验头部session-key
 *
 * @author 长沙商脉科技有限公司
 * @date 2020/11/1 14:30
 */
@Component
public class ApiInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            String token = request.getHeader("token");
            if (StringUtils.isBlank(token)) {
                throw new ServiceResponseException(SysError.UNIDENTIFIED, "未知身份调用!");
            }
            WXMiniProConfigDTO wxMiniProConfig = SysConfigCacheUtil.getWxMiniProConfig();
            if (!token.equals(wxMiniProConfig.getToken())) {
                throw new ServiceResponseException(SysError.UNIDENTIFIED, "未知身份调用!");
            }
            if (!wxMiniProConfig.isEnabled()) {
                throw new ServiceResponseException(SysError.UNIDENTIFIED, "平台已被禁用!");
            }

            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            String sessionKey = request.getHeader("session-key");
            User user = EhCacheUtil.getData(EhCacheUtil.APPLET_USER_CACHE, sessionKey, User.class);
            if (ReflectUtils.requireLogin(method)) {
                if (user == null) {
                    throw new UnLoginException();
                }
                String appletSessionKey = EhCacheUtil.getData(EhCacheUtil.APPLET_SESSION_KEY_CACHE, sessionKey, String.class);
                if (StringUtils.isBlank(appletSessionKey)) {
                    throw new UnLoginException();
                }
            }
            if (user != null) {
                UserThreadLocal.set(user);
            }
            IpThreadLocal.set(ContextUtil.getClientIp(request));
            ServletRequestThreadLocal.set(request);
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        IpThreadLocal.clear();
        ServletRequestThreadLocal.clear();

        UserThreadLocal.clear();
        PagerThreadLocal.clear();
        CacheableThreadLocal.clear();
    }
}